﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PacketRush.Core;
using System.Net;

namespace TestClient
{
    public partial class MainForm : Form
    {
        NetClient _NetClient;
        System.Timers.Timer _Timer;
        volatile bool _Running = false;
        volatile bool _Updating = false;
        public MainForm()
        {
            InitializeComponent();
        }

        private void StartClient()
        {
            if (_NetClient == null)
            {
                ReliableUdpClientNetworkingProvider netProvider = new ReliableUdpClientNetworkingProvider(IPAddress.Parse("127.0.0.1"), 0);
                netProvider.BeforeUpdate += new EventHandler<ReliableUdpEventArgs>(NetProvider_BeforeUpdate);
                _NetClient = new NetClient(netProvider, IPAddress.Parse("127.0.0.1"), 50000);
                _NetClient.LocalConnected += new EventHandler<NetEventArgs>(NetClient_LocalConnected);
                _NetClient.RemoteConnected += new EventHandler<NetEventArgs>(NetClient_RemoteConnected);
                _NetClient.RemoteDisconnected += new EventHandler<NetEventArgs>(NetClient_RemoteDisconnected);
                _NetClient.Error += new EventHandler<NetErrorEventArgs>(NetClient_Error);
                _NetClient.Connect();
                _Timer = new System.Timers.Timer(1);
                _Timer.Elapsed += new System.Timers.ElapsedEventHandler(ClientTimer_Elapsed);
                _Running = true;
                _Timer.Start();
                OutputTextBox.Invoke(new Action<string>(AddOutputMessage), "Client started.");

            }
        }

        void NetProvider_BeforeUpdate(object sender, ReliableUdpEventArgs e)
        {
            ClientPropertyGrid.Invoke(new Action(() => { ClientPropertyGrid.SelectedObject = e.Connection; }));
        }


        void ClientTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (!_Updating)
            {
                _Updating = true;
                if (_Running)
                {
                    try
                    {
                        _NetClient.Update();
                    }
                    catch (Exception x)
                    {
                        OutputTextBox.Invoke(new Action<string>(AddOutputMessage), x.Message + "\r\n" + x.StackTrace);

                    }
                }
                else
                {
                    _Timer.Stop();
                    _NetClient.Disconnect();

                    _Timer = null;
                    _NetClient = null;

                    TopToolBar.Invoke(new Action(() => { ConnectButton.Enabled = true; }));
                    OutputTextBox.Invoke(new Action<string>(AddOutputMessage), "Client stopped.");
                }

                _Updating = false;
            }
        }


        void NetClient_Error(object sender, NetErrorEventArgs e)
        {
            OutputTextBox.Invoke(new Action<string>(AddOutputMessage), e.SocketErrorCode.ToString());
        }

        void NetClient_LocalConnected(object sender, NetEventArgs e)
        {
            OutputTextBox.Invoke(new Action<string>(AddOutputMessage), "Local connected with id " + e.ConnectionId.ToString() + ".");            
        }

        void NetClient_RemoteDisconnected(object sender, NetEventArgs e)
        {
            OutputTextBox.Invoke(new Action<string>(AddOutputMessage), "Remote disconnected with id " + e.ConnectionId.ToString() + ".");            
        }

        void NetClient_RemoteConnected(object sender, NetEventArgs e)
        {
            OutputTextBox.Invoke(new Action<string>(AddOutputMessage), "Remote connected with id " + e.ConnectionId.ToString() + ".");            
        }

        public void AddOutputMessage(string message)
        {
            OutputTextBox.Text += "\r\n> " + message;
            OutputTextBox.Select(OutputTextBox.Text.Length - 1, 0);
            OutputTextBox.ScrollToCaret();
        }

        private void ConnectButton_Click(object sender, EventArgs e)
        {
            if (!_Running)
            {
                StartClient();
            }
            else
            {
                _Running = false;
                ConnectButton.Enabled = false;
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
        }
    }
}
